//
//  GSModelsManager.h
//  AgileNYC
//
//  Created by German on 30.05.14.
//  Copyright (c) 2014 Softlegion. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "GSUser.h"
#import "GSEvent.h"


/// Notification names

// Renew means: delete all items and load from server a full list
extern NSString * const eventsWillRenewNotification;
extern NSString * const eventsDidRenewNotification;
extern NSString * const eventsDidNotRenewNotification;

extern NSString * const contactsWillRenewNotification;
extern NSString * const contactsDidRenewNotification;
extern NSString * const contactsDidNotRenewNotification;

//Update means: check and update (delete, insert, change) only changed items
extern NSString * const eventsWillUpdateNotification;
extern NSString * const eventsDidUpdateNotification;
extern NSString * const eventsDidNotUpdateNotification; //In case of error or nothing was changed

extern NSString * const contactsWillUpdateNotification;
extern NSString * const contactsDidUpdateNotification;
extern NSString * const contactsDidNotUpdateNotification;

extern NSString * const profileWillUpdateNotification;
extern NSString * const profileDidUpdateNotification;
extern NSString * const profileDidNotUpdateNotification;

extern NSString * const profileImageWillUpdateNotification;
extern NSString * const profileImageDidUpdateNotification;
extern NSString * const profileImageDidNotUpdateNotification;

extern NSString * const contactImageWillUpdateNotification;
extern NSString * const contactImageDidUpdateNotification;
extern NSString * const contactImageDidNotUpdateNotification;

extern NSString * const contactImageUpdateContactIdKey;
extern NSString * const eventImageUpdateEventIdKey;


@interface SGSModelsManager : NSObject

+(SGSModelsManager*) sharedModelsManager;

@property (copy, nonatomic) NSString * deviceToken;

-(void) saveDeviceToken:(NSData*) deviceToken;
-(void) saveDeviceTokenError:(NSString*) error;

@property (strong,nonatomic) GSUser * currentUser;
@property (strong,nonatomic) GSEvent * currentEvent;
@property (strong,nonatomic) GSUser * currentContact;
@property (strong,nonatomic) GSUser * currentRequester;

@property (strong,nonatomic) NSArray * arrayOfEvents;
@property (strong,nonatomic) NSArray * arrayOfContacts;

//@property (strong, nonatomic) NSString * controllerToBeOpened;

//Settings

-(void) synchronizeDB;
//-(BOOL) saveLocalDB;

@property (assign, nonatomic) BOOL isFirstRun;

-(BOOL) loadSettings;
-(BOOL) saveSettings;
-(BOOL) clearSettings;

// User

-(void) checkUserEmail:(NSString*) eMail
                onComplete:(void(^)(BOOL result, NSString * errorString)) completitionBlock;

-(void) loginUserWithEmail:(NSString*) eMail
                  password:(NSString*) password
                onComplete:(void(^)(BOOL result, NSString * errorString)) completitionBlock;

-(void) loginUserWithSocial:(NSString*) eMail
                 socialType:(NSInteger) socialType
                onComplete:(void(^)(BOOL result, NSError * error)) completitionBlock;

-(void) createUserWithEmail:(NSString*) eMail
                   password:(NSString*) password
                 onComplete:(void(^)(BOOL result, NSError * error)) completitionBlock;

-(void) createUserWithSocial:(NSString*) eMail
                  socialType:(NSInteger) socialType
                 onComplete:(void(^)(BOOL result, NSError * error)) completitionBlock;

-(void) saveUserChangesAndSendToServer:(GSUser*) user
                           newUserData:(NSDictionary*) userDict
                            onComplete:(void(^)(BOOL result)) completitionBlock;

//-(void) saveUserInfoToServer:(GSUser*) user
//                  onComplete:(void(^)(BOOL result)) completitionBlock;

//-(void) sendPhotoToServerForUser:(GSUser*) user
//                      onComplete:(void(^)(BOOL result)) completitionBlock;

-(BOOL) checkUserLogin;

//-(void) loadMyProfileInfoFromServer;

// Events
-(NSUInteger) eventsCount;

-(GSEvent *) eventByIndex:(NSUInteger) index;
-(GSEvent *) eventByID:(NSNumber*) eventID;

-(void) makeEventCurrentByID:(NSNumber*) eventID;
-(void) makeEventCurrentByIndex:(NSUInteger) index;

-(void) requestImageForEventByEvent:(GSEvent *) event
                    //loadToImageView:(UIImageView*) imageView;
                         onComplete:(void(^)(BOOL result, UIImage * image)) completitionBlock;

-(void) requestImageForEventByIndex:(NSInteger) eventIndex
                    //loadToImageView:(UIImageView*) imageView;
                         onComplete:(void(^)(BOOL result, UIImage * image)) completitionBlock;

-(void) checkInOnEvent:(GSEvent*) event
               checkIn:(BOOL) checkIn
            onComplete:(void(^)(BOOL result, NSString * errorMessage)) completitionBlock;

-(void) rateEvent:(GSEvent*) event
           rating:(NSInteger) rating
       onComplete:(void(^)(BOOL result)) completitionBlock;


// Contacts
-(NSUInteger) contactsCount;

-(GSUser *) contactByIndex:(NSUInteger) index;
-(GSUser *) contactBySessionID:(NSNumber*) sessionID;

-(void) makeContactCurrentByID:(NSNumber*) contactID;
-(void) makeContactCurrentByIndex:(NSUInteger) index;

-(void) requestImageForContactByContact:(GSUser *) contact
        //                loadToImageView:(UIImageView*) imageView;
                             onComplete:(void(^)(BOOL result, UIImage * image)) completitionBlock;

-(void) requestImageForContactByIndex:(NSInteger) contactIndex
                    //loadToImageView:(UIImageView*) imageView;
                           onComplete:(void(^)(BOOL result, UIImage * image)) completitionBlock;

-(void) saveUserImageAndSendToServer:(UIImage*) userImage
                             forUser:(GSUser *) user;

-(void) deleteUserImageAndSendToServer:(GSUser *) user;

-(void) saveContactNotesAndSendToServer:(GSUser*) contact notes:(NSString*) notes;


// Deletion
-(BOOL) deleteAllContactsFromLocalDB;
-(BOOL) deleteAllUsersFromLocalDB;
-(BOOL) deleteAllEventsFromLocalDB;
-(BOOL) deleteMyProfileFromLocalDB;

//Connections

-(void) sendConnectionRequest:(NSString*) toUserID
                   onComplete:(void(^)(BOOL result, NSError * error)) completitionBlock;
//-(void) checkConnectionRequest:(void(^)(BOOL result, NSInteger requesterId, NSString * requesterName)) completitionBlock;
-(void) checkConnectionRequest:(void(^)(BOOL result)) completitionBlock;
-(void) replyForConnectionRequest:(NSString*) toUserID
                           answer:(BOOL) answer
                       onComplete:(void(^)(BOOL result)) completitionBlock;
-(void) deleteContact:(GSUser*) contact
           onComplete:(void(^)(BOOL result, NSError * error)) completitionBlock;

-(void) replyForReplyForConnectionRequest;

// Social Networks

-(void) makeLoginWithFacebook:(GSUser*) currentUser
                   onComplete: (void(^)(BOOL result)) completionBlock;

-(void) makeLoginWithLinkedIn:(GSUser*) currentUser
                   onComplete: (void(^)(BOOL result)) completionBlock;

-(void) makeLoginWithGooglePlus:(GSUser*) currentUser
                     onComplete: (void(^)(BOOL result)) completionBlock;

-(void) updateIdFromFacebookForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) updateIdAndImageFromFacebookForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) clearIdForFacebookForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) showProfileInFacebookForURL:(NSString*) url onComplete:(void(^)(BOOL result)) completionBlock;

-(void) updateIdFromLinkedInForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) updateIdAndImageFromLinkedInForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) clearIdForLinkedInForCurrentUser:(void(^)(BOOL result)) completionBlock;

-(void) updateIdFromGooglePlusForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) updateIdAndImageFromGooglePlusForCurrentUser:(void(^)(BOOL result)) completionBlock;
-(void) clearIdForGooglePlusForCurrentUser:(void(^)(BOOL result)) completionBlock;


// Local database

@property (readonly, strong, nonatomic) NSManagedObjectContext *defaultManagedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;

- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;


@end
